package c18类加载和反射;

import java.lang.reflect.*;

public class s22利用反射获取并操作属性 {

	public static void main(String[] args) throws ClassNotFoundException,
			InstantiationException, IllegalAccessException, NoSuchMethodException,
			SecurityException, IllegalArgumentException, InvocationTargetException,
			NoSuchFieldException {

		TestFieldName t = new TestFieldName();
		Class<?> clazz = t.getClass();

		Field[] fs = clazz.getDeclaredFields();
		for (Field f : fs) {
			System.err.println(f);
		}
		/**
		 * 1. 获取属性值
		 */
		//获取public属性pubi
		Field fpubi = clazz.getField("pubi");//pubi不强制要求有getter和setter
		System.err.println(fpubi.getInt(t));//获取pubi的值。必须传入对象t，因为属性i是属于一个具体的对象的！
		fpubi.setInt(t, 100);//设置pubi的值。同上
		System.err.println(fpubi.getInt(t));

		//获取private属性prii。除了要设置访问权限外，其他与上面差不多~
		Field fprii = clazz.getDeclaredField("prii");
		fprii.setAccessible(true);//设置属性的访问权限：true为取消访问权限检查，这样才能访问private属性！
		System.err.println(fprii.getInt(t));
		fprii.setInt(t, -1);
		System.err.println(fprii.getInt(t));

		//获取静态属性
		Field fsb = clazz.getDeclaredField("sb");
		System.err.println(fsb.getBoolean(null));//因为静态属性属于类，属于应该传入null！当然传入t也可以
		fsb.setBoolean(null, false);
		System.err.println(fsb.getBoolean(null));

		/**
		 * 2. 获取属性类型
		 */
		Field fmap = clazz.getField("map");
		Class<?> ct = fmap.getType();//获取普通类型
		System.err.println(ct);

		Type gt = fmap.getGenericType();//获取泛型类型。Type是接口，由Class实现！
		if (gt instanceof ParameterizedType) {//ParameterizedType 是 Type 的子接口
			ParameterizedType pt = (ParameterizedType) gt;//强制转换为参数化类型对象
			Type rt = pt.getRawType();//获取原始类型，与 f.getType(); 的效果一样
			System.err.println(rt);

			Type gts[] = pt.getActualTypeArguments();//获取实际上的各个泛型形参
			for (int i = 0; i < gts.length; i++) {
				System.err.println("第" + i + "个泛型形参：" + gts[i]);
			}
		}

		/**
		 * 3. 其他方法
		 */
		//返回所有修饰符串联的表示形式，因为可能有多个修饰符，所有以s结尾，但是返回的是int！
		System.err.println(Modifier.toString(fpubi.getModifiers()));
		System.err.println(Modifier.toString(fprii.getModifiers()));
		System.err.println(Modifier.toString(fsb.getModifiers()));//public static！
		System.err.println(Modifier.toString(fmap.getModifiers()));
		System.err.println(fpubi.isEnumConstant());//是否是枚举类型
	}

}
